#region Copyright (c) 2006-2009 Widgetsphere LLC, All Rights Reserved
//--------------------------------------------------------------------- *
//                          Widgetsphere  LLC                           *
//             Copyright (c) 2006-2009 All Rights reserved              *
//                                                                      *
//                                                                      *
//This file and its contents are protected by United States and         *
//International copyright laws.  Unauthorized reproduction and/or       *
//distribution of all or any portion of the code contained herein       *
//is strictly prohibited and will result in severe civil and criminal   *
//penalties.  Any violations of this copyright will be prosecuted       *
//to the fullest extent possible under law.                             *
//                                                                      *
//THE SOURCE CODE CONTAINED HEREIN AND IN RELATED FILES IS PROVIDED     *
//TO THE REGISTERED DEVELOPER FOR THE PURPOSES OF EDUCATION AND         *
//TROUBLESHOOTING. UNDER NO CIRCUMSTANCES MAY ANY PORTION OF THE SOURCE *
//CODE BE DISTRIBUTED, DISCLOSED OR OTHERWISE MADE AVAILABLE TO ANY     *
//THIRD PARTY WITHOUT THE EXPRESS WRITTEN CONSENT OF WIDGETSPHERE LLC   *
//                                                                      *
//UNDER NO CIRCUMSTANCES MAY THE SOURCE CODE BE USED IN WHOLE OR IN     *
//PART, AS THE BASIS FOR CREATING A PRODUCT THAT PROVIDES THE SAME, OR  *
//SUBSTANTIALLY THE SAME, FUNCTIONALITY AS ANY WIDGETSPHERE PRODUCT.    *
//                                                                      *
//THE REGISTERED DEVELOPER ACKNOWLEDGES THAT THIS SOURCE CODE           *
//CONTAINS VALUABLE AND PROPRIETARY TRADE SECRETS OF WIDGETSPHERE,      *
//INC.  THE REGISTERED DEVELOPER AGREES TO EXPEND EVERY EFFORT TO       *
//INSURE ITS CONFIDENTIALITY.                                           *
//                                                                      *
//THE END USER LICENSE AGREEMENT (EULA) ACCOMPANYING THE PRODUCT        *
//PERMITS THE REGISTERED DEVELOPER TO REDISTRIBUTE THE PRODUCT IN       *
//EXECUTABLE FORM ONLY IN SUPPORT OF APPLICATIONS WRITTEN USING         *
//THE PRODUCT.  IT DOES NOT PROVIDE ANY RIGHTS REGARDING THE            *
//SOURCE CODE CONTAINED HEREIN.                                         *
//                                                                      *
//THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE.              *
//--------------------------------------------------------------------- *
#endregion
using System;
using System.Reflection;
using System.IO;
using System.Collections;

using VSLangProj;
using EnvDTE;

using interop = System.Runtime.InteropServices;

using Widgetsphere.Generator.Common.Logging;
using Widgetsphere.Generator.Common.GeneratorFramework;

namespace Widgetsphere.Generator.Common.Util
{
	/// <summary>
	/// Summary description for EnvDTEHelper.
	/// </summary>
	public class EnvDTEHelper
	{

		#region member variables
		private _DTE _applicationObject;
		private static EnvDTEHelper _instance = null;
		private SolutionEvents _solutionEvents;
		#endregion

		public enum FileStateConstants
		{
			/// <summary>
			/// The file was successfully written
			/// </summary>
			Success,
			/// <summary>
			/// The file existed and was not marked as overwrite, so it was skipped
			/// </summary>
			Skipped,
			/// <summary>
			/// The write failed because the file was in use or read-only
			/// </summary>
			Failed,
		}

		private EnvDTEHelper()
		{

		}

		public _DTE ApplicationObject
		{
			get
			{
				return _applicationObject;
			}
		}

		public void SetDTE(_DTE applicationObject)
		{
			if (_applicationObject == null)
			{
				_applicationObject = applicationObject;
				_solutionEvents = (EnvDTE.SolutionEvents)_applicationObject.Events.SolutionEvents;
			}
		}

		public static EnvDTEHelper Instance
		{
			get
			{
				if (_instance == null)
				{
					_instance = new EnvDTEHelper();
				}
				return _instance;
			}
		}

		public SolutionEvents SolutionEvents
		{
			get
			{
				return _solutionEvents;
			}
		}

		public Project CurrentProject
		{
			get
			{
				System.Array projects = (System.Array)_applicationObject.DTE.ActiveSolutionProjects;
				if (projects.Length != 1)
				{
					return null;
				}
				Project currentProject = (Project)projects.GetValue(0);
				return currentProject;
			}
		}

		public static ProjectItem AddFolder(Project project, string folderName)
		{
			return project.ProjectItems.AddFolder(folderName, Constants.vsProjectItemKindPhysicalFolder);
		}

		public static ProjectItem AddFolder(ProjectItem projectItem, string folderName)
		{
			return projectItem.ProjectItems.AddFolder(folderName, Constants.vsProjectItemKindPhysicalFolder);
		}

		#region AddProjectItem

		public ProjectItem AddProjectItem(string fileName, out FileStateInfo fileStateInfo)
		{
			fileStateInfo = new FileStateInfo();
			try
			{
				EnvDTE.ProjectItem newItem = CurrentProject.ProjectItems.AddFromFile(fileName);
				fileStateInfo.FileState = FileStateConstants.Success;
				fileStateInfo.FileName = fileName;
				return newItem;
			}
			catch (Exception ex)
			{
				fileStateInfo.FileState = FileStateConstants.Failed;
				return null;
			}

		}

		public static ProjectItem AddProjectItem(Project project, string fileName, out FileStateInfo fileStateInfo)
		{
			fileStateInfo = new FileStateInfo();
			try
			{
				fileStateInfo.FileState = FileStateConstants.Success;
				fileStateInfo.FileName = fileName;
				return project.ProjectItems.AddFromFileCopy(fileName);
			}
			catch (Exception ex)
			{
				fileStateInfo.FileState = FileStateConstants.Failed;
				return null;
			}
		}

		public static ProjectItem AddProjectItem(Project project, string fileContent, string relativePathAndName, out FileStateInfo fileStateInfo)
		{
			return AddProjectItem(project, fileContent, relativePathAndName, true, out fileStateInfo);
		}

		public static ProjectItem AddProjectItem(Project project, string fileContent, string relativePathAndName, bool overwrite, out FileStateInfo fileStateInfo)
		{
			fileStateInfo = new FileStateInfo();
			fileStateInfo.FileState = FileStateConstants.Failed;
			FileInfo newFile = null;
			if (project.Kind == Constants.vsProjectKindUnmodeled)
			{
				DTE applicationObject = (DTE)EnvDTEHelper.Instance._applicationObject;
				//Handle on Solution Explorer window
				EnvDTE.Window slnExplorer = applicationObject.Windows.Item(Constants.vsWindowKindSolutionExplorer);
				UIHierarchy slnHierarchy = (UIHierarchy)slnExplorer.Object;
				slnExplorer.Activate();
				UIHierarchyItem dbProject = EnvDTEHelper.Instance.Find(project);
				dbProject.Select(vsUISelectionType.vsUISelectionTypeSelect);
			}
			else
			{
				FileInfo currentProjectFile = new FileInfo(project.FileName);
				string fullName = StringHelper.EnsureDirectorySeperatorAtEnd(currentProjectFile.Directory.FullName) + relativePathAndName;
				fileStateInfo.FileName = fullName;
				newFile = new FileInfo(fullName);
				if (newFile.Exists && !overwrite)
				{
					fileStateInfo.FileState = FileStateConstants.Skipped;
					return null;
				}
				else if (newFile.Exists && (newFile.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
				{
					fileStateInfo.FileState = FileStateConstants.Failed;
					return null;
				}
				if (!newFile.Directory.Exists)
					newFile.Directory.Create();
				using (StreamWriter sw = newFile.CreateText())
				{
					sw.Write(fileContent);
				}
			}

			try
			{
				fileStateInfo.FileState = FileStateConstants.Success;
				return project.ProjectItems.AddFromFile(newFile.FullName);
			}
			catch (Exception ex)
			{
				fileStateInfo.FileState = FileStateConstants.Failed;
				return null;
			}

		}

		#endregion

		public static void AddReference(Project project, string assemblyLocation)
		{
			VSProject vsProject = CastToVSProject(project);
			vsProject.References.Add(assemblyLocation);
		}

		public static VSProject CastToVSProject(Project project)
		{
			if ((project.Kind == PrjKind.prjKindVBProject) || (project.Kind == PrjKind.prjKindCSharpProject) || (project.Kind == PrjKind.prjKindVSAProject))
			{
				return (VSProject)project.Object;
			}
			else
				throw new Exception("The project is not a Visual Basic or C# project.");
		}

		public static void SetProperties(ProjectItem projectItem, Hashtable properties)
		{
			foreach (DictionaryEntry de in properties)
			{
				EnvDTEHelper.SetProperty(projectItem, (string)de.Key, de.Value);
			}
		}

		public static void SetProperty(ProjectItem projectItem, string propertyName, object propertyValue)
		{
			foreach (Property property in projectItem.Properties)
			{
				if (StringHelper.Match(property.Name, propertyName))
				{
					property.Value = propertyValue;
				}
			}
		}

		public ProjectItem AddProjectItem(ProjectItem parent, string fileName, out FileStateInfo fileStateInfo)
		{
			fileStateInfo = new FileStateInfo();
			try
			{
				fileStateInfo.FileName = fileName;
				EnvDTE.ProjectItem newItem = parent.ProjectItems.AddFromFileCopy(fileName);
				fileStateInfo.FileState = FileStateConstants.Success;
				return newItem;
			}
			catch (System.Runtime.InteropServices.COMException ex)
			{
				if (ex.Message.ToLower().Contains("already exists"))
					fileStateInfo.FileState = FileStateConstants.Skipped;
				else
					fileStateInfo.FileState = FileStateConstants.Failed;
				return null;
			}
			catch (Exception ex)
			{
				fileStateInfo.FileState = FileStateConstants.Failed;
				throw;
			}
		}

		public ProjectItem AddProjectItem(ProjectItem parent, string fileName, bool overwrite, out FileStateInfo fileStateInfo)
		{
			fileStateInfo = new FileStateInfo();
			FileInfo currentParentFile = new FileInfo(EnvDTEHelper.GetFileName(parent));
			FileInfo newFile = new FileInfo(StringHelper.EnsureDirectorySeperatorAtEnd(currentParentFile.Directory.FullName) + fileName);
			fileStateInfo.FileName = newFile.FullName;
			if (newFile.Exists && !overwrite)
			{
				fileStateInfo.FileState = FileStateConstants.Skipped;
				return null;
			}
			else
			{
				EnvDTE.ProjectItem newItem = parent.ProjectItems.AddFromFileCopy(fileName);
				fileStateInfo.FileState = FileStateConstants.Success;
				return newItem;
			}
		}

		public ProjectItem AddProjectItem(ProjectItem parent, string fileName, string content, bool overwrite, out FileStateInfo fileStateInfo)
		{
			fileStateInfo = new FileStateInfo();
			FileInfo fi = new FileInfo(EnvDTEHelper.GetFileName(parent));
			string directory = StringHelper.EnsureDirectorySeperatorAtEnd(fi.DirectoryName);
			string fullName = directory + fileName;
			fileStateInfo.FileName = fullName;
			StreamWriter sw = null;
			try
			{
				FileInfo fi2 = new FileInfo(fullName);
				if (File.Exists(fullName) && !overwrite)
				{
					fileStateInfo.FileState = FileStateConstants.Skipped;
					return null;
				}
				else if (fi2.Exists && (fi2.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
				{
					fileStateInfo.FileState = FileStateConstants.Failed;
					return null;
				}
				else
				{
					sw = File.CreateText(fullName);
					sw.Write(content);
					fileStateInfo.FileState = FileStateConstants.Success;
				}
			}
			catch (Exception ex)
			{
				fileStateInfo.FileState = FileStateConstants.Failed;
				//GlobalHelper.SetErr(ex);
			}
			finally
			{
				if (sw != null)
					sw.Close();
			}
			EnvDTE.ProjectItem newItem = parent.ProjectItems.AddFromFile(fullName);
			return newItem;
		}

		public ProjectItem AddProjectItem(ProjectItem parent, string fileName, string content)
		{
			FileInfo fi = new FileInfo(EnvDTEHelper.GetFileName(parent));
			string directory = StringHelper.EnsureDirectorySeperatorAtEnd(fi.DirectoryName);
			string fullName = directory + fileName;
			StreamWriter sw = null;
			try
			{
				sw = File.CreateText(fullName);
				sw.Write(content);
			}
			catch (Exception ex)
			{
				//GlobalHelper.SetErr(ex);
			}
			finally
			{
				if (sw != null)
					sw.Close();
			}
			EnvDTE.ProjectItem newItem = parent.ProjectItems.AddFromFile(fullName);
			return newItem;
		}

		public ProjectItem GetProjectItem(string projectName, string parentItemRelativeName)
		{
			return GetProjectItem(projectName, parentItemRelativeName, ProjectItemType.File);
			string relativeFolders = string.Empty;
			string[] folders = parentItemRelativeName.Split(new char[] { '\\' });
			for (int ii = 0; ii < folders.Length - 1; ii++)
			{
				relativeFolders = relativeFolders + @"\" + folders[ii];
			}
			ProjectItem folder = this.GetProjectFolder(projectName, relativeFolders);
			foreach (ProjectItem subItem in folder.ProjectItems)
			{
				if (subItem.Kind == Constants.vsProjectItemKindPhysicalFile && subItem.Name == folders[folders.Length - 1])
				{
					return subItem;
				}
			}
			return null;
		}

		public ProjectItem GetProjectItem(string projectName, string parentRelativeName, ProjectItemType parentItemType)
		{
			string relativeFolder = string.Empty;
			string parentFileName = string.Empty;
			if (parentItemType == ProjectItemType.File)
			{
				string[] folders = parentRelativeName.Split(new char[] { '\\' });
				for (int ii = 0; ii < folders.Length - 1; ii++)
				{
					relativeFolder = relativeFolder + @"\" + folders[ii];
				}
				parentFileName = folders[folders.Length - 1];
			}
			else
			{
				relativeFolder = parentRelativeName;
			}
			if (relativeFolder != string.Empty && relativeFolder != "\\")
			{
				ProjectItem folder = this.GetProjectItem(GetProject(projectName), relativeFolder);
				if (parentItemType == ProjectItemType.File)
				{
					foreach (ProjectItem subItem in folder.ProjectItems)
					{
						if (subItem.Kind == Constants.vsProjectItemKindPhysicalFile && subItem.Name == parentFileName)
						{
							return subItem;
						}
					}
					return null;
				}
				return folder;
			}
			else
			{
				Project projectToAddTo = this.GetProject(projectName);
				foreach (ProjectItem projectItem in projectToAddTo.ProjectItems)
				{
					if (projectItem.Kind == Constants.vsProjectItemKindPhysicalFile && projectItem.Name == parentFileName)
					{
						return projectItem;
					}
				}
				return null;
			}
		}

		public void SelectProjectItem(ProjectItem pi)
		{
			ActivateSolutionHierarchy();
			UIHierarchyItem uiHierarchyItem = Find(pi);
			uiHierarchyItem.Select(vsUISelectionType.vsUISelectionTypeSelect);
		}


		public FileInfo[] Find(string fileExtension)
		{
			ArrayList fileInfos = new ArrayList();
			foreach (UIHierarchyItem hierarchyItem in SolutionHierarchy.UIHierarchyItems.Item(1).UIHierarchyItems)
			{
				if (hierarchyItem.Name == "Solution Items")
				{
					foreach (UIHierarchyItem subHierarchyItem in hierarchyItem.UIHierarchyItems)
					{
						if (subHierarchyItem.Name.EndsWith(".xml"))
						{
							FileInfo fi = new FileInfo(StringHelper.EnsureDirectorySeperatorAtEnd(this.SolutionDirectory.FullName) + "doc/" + subHierarchyItem.Name);
							if (fi.Extension == fileExtension)
							{
								fileInfos.Add(fi);
							}
						}
					}
				}
			}
			return (FileInfo[])fileInfos.ToArray(typeof(FileInfo));
		}

		public UIHierarchyItem Find(Project project)
		{
			UIHierarchyItem retVal = null;
			foreach (UIHierarchyItem hierarchyItem in SolutionHierarchy.UIHierarchyItems)
			{
				if (hierarchyItem.Object == project)
					retVal = hierarchyItem;
				else
					retVal = Find(hierarchyItem, project);
				if (retVal != null)
					break;
			}
			return retVal;
		}

		private UIHierarchyItem Find(UIHierarchyItem hierarchyItem, Project project)
		{
			UIHierarchyItem retVal = null;
			foreach (UIHierarchyItem childItem in hierarchyItem.UIHierarchyItems)
			{
				if (childItem.Name == project.Name)
				{
					if (ReflectionHelper.ImplementsInterface(hierarchyItem.Object, typeof(Solution)))
						retVal = childItem;
				}
				else
					retVal = Find(childItem, project);
				if (retVal != null)
					break;
			}
			return retVal;
		}

		public UIHierarchyItem Find(ProjectItem pi)
		{
			UIHierarchyItem retVal = null;
			foreach (UIHierarchyItem hierarchyItem in SolutionHierarchy.UIHierarchyItems)
			{
				if (hierarchyItem.Object == pi)
					retVal = hierarchyItem;
				else
					retVal = Find(hierarchyItem, pi);
				if (retVal != null)
					break;
			}
			return retVal;
		}

		private UIHierarchyItem Find(UIHierarchyItem hierarchyItem, ProjectItem pi)
		{
			UIHierarchyItem retVal = null;
			foreach (UIHierarchyItem childItem in hierarchyItem.UIHierarchyItems)
			{
				if (childItem.Object == pi)
					retVal = hierarchyItem;
				else
					retVal = Find(childItem, pi);
				if (retVal != null)
					break;
			}
			return retVal;
		}

		public UIHierarchy SolutionHierarchy
		{
			get
			{
				Window solutionWindow = (Window)_applicationObject.Windows.Item(Constants.vsWindowKindSolutionExplorer);
				UIHierarchy solutionHierarchy = (UIHierarchy)solutionWindow.Object;
				return solutionHierarchy;
			}
		}

		public void ActivateSolutionHierarchy()
		{
			Window solutionWindow = (Window)_applicationObject.Windows.Item(Constants.vsWindowKindSolutionExplorer);
			solutionWindow.Activate();
		}

		public static string GetFileName(ProjectItem pi)
		{
			return pi.get_FileNames(1);
		}

		public ProjectItem CurrentProjectItem
		{
			get
			{
				EnvDTE.SelectedItems selectedItems = _applicationObject.SelectedItems;
				EnvDTE.SelectedItem selectedItem = selectedItems.Item(1);
				if (selectedItem != null)
				{
					return selectedItem.ProjectItem;
				}
				return null;
			}
		}

		public bool IsModelFileSelected
		{
			get
			{
				if (CurrentProjectItem != null)
				{
					return GeneratorHelper.IsModelFile(CurrentProjectItem);
				}
				return false;
			}
		}

		public Project CreateProjectFromTemplate(string template, string projectName)
		{
			try
			{
				FileInfo currentSolution = new FileInfo(CurrentSolution.FullName);
				DirectoryInfo currentSolutionDirectory = currentSolution.Directory;
				DirectoryInfo newProjectLocation = null;
				if (currentSolutionDirectory.GetDirectories(projectName).Length > 0)
				{
					//throw new Exception("Directory Already exists.");
					return null;
				}
				else
				{
					newProjectLocation = currentSolutionDirectory.CreateSubdirectory(projectName);
					Project retval = CurrentSolution.AddFromTemplate(template, newProjectLocation.FullName, projectName, false);
					return retval;
				}
			}
			catch (Exception ex)
			{
				throw;
			}
		}

		public Project CreateCSharpProject(string name)
		{
			try
			{
				FileInfo currentSolution = new FileInfo(CurrentSolution.FullName);
				DirectoryInfo currentSolutionDirectory = currentSolution.Directory;
				DirectoryInfo newProjectLocation = null;
				if (currentSolutionDirectory.GetDirectories(name).Length > 0)
					throw new Exception("Directory Already exists.");
				else
					newProjectLocation = currentSolutionDirectory.CreateSubdirectory(name);

				string installLocation = InstallLocationHelper.VisualStudio2005().FullName;
				Project retval = CurrentSolution.AddFromTemplate(installLocation + @"Common7\IDE\ProjectTemplatesCache\CSharp\Windows\1033\EmptyProject.zip\emptyproject.csproj", newProjectLocation.FullName, name, false);
				return retval;
			}
			catch (Exception ex)
			{
				throw;
			}
		}

		public Project CreateDatabaseProject(string name)
		{
			try
			{
				FileInfo currentSolution = new FileInfo(CurrentSolution.FullName);
				DirectoryInfo currentSolutionDirectory = currentSolution.Directory;
				DirectoryInfo newProjectLocation = null;
				if (currentSolutionDirectory.GetDirectories(name).Length > 0)
					throw new Exception("Directory Already exists.");
				else
					newProjectLocation = currentSolutionDirectory.CreateSubdirectory(name);

				string installLocation = InstallLocationHelper.VisualStudio2005().FullName;
				Project retval = CurrentSolution.AddFromTemplate(installLocation + @"Common7\IDE\ProjectTemplatesCache\CSharp\Windows\1033\EmptyDatabase.zip\Database.mdf", newProjectLocation.FullName, name, false);
				return retval;
			}
			catch (Exception ex)
			{
				throw;
			}
		}

		public DirectoryInfo SolutionDirectory
		{
			get
			{
				FileInfo fi = new FileInfo(CurrentSolution.FullName);
				return fi.Directory;
			}
		}

		public EnvDTE.Solution CurrentSolution
		{
			get
			{
				return _applicationObject.Solution;
			}
		}

		public bool ProjectExists(string projectName)
		{
			return !(EnvDTEHelper.Instance.GetProject(projectName) == null);
		}

		public Project GetProject(string projectName)
		{
			foreach (Project proj in CurrentSolution.Projects)
			{
				try
				{
					if (StringHelper.Match(proj.Name, projectName, true))
					{
						return proj;
					}
				}
				catch (Exception ex)
				{
					System.Diagnostics.Debug.WriteLine(ex.ToString());
				}
			}
			return null;
		}

		public ProjectItem GetProjectFolder(string projectName, string projectLocation)
		{
			Project proj = this.GetProject(projectName);
			if (proj != null)
				return GetProjectFolder(proj, projectLocation);
			else
				return null;
		}


		public ProjectItem GetProjectItem(ProjectItem parentItem, string projectItem)
		{
			if (projectItem != string.Empty)
			{
				ProjectItem currentProjectItem = null;
				foreach (ProjectItem pi in parentItem.ProjectItems)
				{
					if (pi.Name == projectItem)
					{
						currentProjectItem = pi;
					}
				}
				if (currentProjectItem == null)
				{
					currentProjectItem = AddFolder(parentItem, projectItem);
				}
				return currentProjectItem;
			}
			else
			{
				return parentItem;
			}
		}

		public ProjectItem GetProjectItem(Project project, string projectItemString)
		{
			ProjectItem currentProjectItem = null;
			string currentFolder = string.Empty;
			string folder = string.Empty;
			projectItemString = projectItemString.TrimStart(new char[] { '\\' });
			string[] folders = projectItemString.Split(new char[] { '\\' });
			if (folders.Length > 0)
			{
				folder = folders[0];
				foreach (ProjectItem pi in project.ProjectItems)
				{
					if (pi.Name == folder)
					{
						currentProjectItem = pi;
					}
				}
				if (currentProjectItem == null)
				{
					currentProjectItem = AddFolder(project, folder);
				}
			}

			for (int ii = 1; ii < folders.Length; ii++)
			{
				currentProjectItem = GetProjectItem(currentProjectItem, folders[ii]);
			}
			return currentProjectItem;

		}

		public ProjectItem GetProjectFolder(Project project, string folderString)
		{
			ProjectItem currentProjectItem = null;
			string currentFolder = string.Empty;
			string folder = string.Empty;
			folderString = folderString.TrimStart(new char[] { '\\' });
			string[] folders = folderString.Split(new char[] { '\\' });
			if (folders.Length > 0)
			{
				folder = folders[0];
				foreach (ProjectItem pi in project.ProjectItems)
				{
					if (pi.Kind == Constants.vsProjectItemKindPhysicalFolder || pi.Kind == Constants.vsProjectItemKindVirtualFolder)
					{
						if (pi.Name == folder)
						{
							currentProjectItem = pi;
						}
					}
				}
				if (currentProjectItem == null)
				{
					currentProjectItem = AddFolder(project, folder);
				}
			}

			for (int ii = 1; ii < folders.Length; ii++)
			{
				currentProjectItem = GetProjectFolder(currentProjectItem, folders[ii]);
			}
			return currentProjectItem;

		}

		public ProjectItem GetProjectFolder(ProjectItem parentItem, string folder)
		{
			if (folder != string.Empty)
			{
				ProjectItem currentProjectItem = null;
				foreach (ProjectItem pi in parentItem.ProjectItems)
				{
					if (pi.Kind == Constants.vsProjectItemKindPhysicalFolder || pi.Kind == Constants.vsProjectItemKindVirtualFolder)
					{
						if (pi.Name == folder)
						{
							currentProjectItem = pi;
						}
					}
				}
				if (currentProjectItem == null)
				{
					currentProjectItem = AddFolder(parentItem, folder);
				}
				return currentProjectItem;
			}
			else
			{
				return parentItem;
			}
		}

		/*
    public Command CreateAddinMenu(CommandBar commandBar, AddIn addInInstance, string AName, string ACaption, string ADescription, int AImageIndex, string AShortCut, bool ASeparator)
    {
      try
      {
        Command CommandObj;
        CommandBarButton ButtonObj;

        object[] o = new object[1];

        // Create add-in
        CommandObj = (Command)_applicationObject.Commands.AddNamedCommand(addInInstance, AName, ACaption, ADescription, false, AImageIndex, ref o, 1 + 2);
        //add shortcut
        if (AShortCut != string.Empty)
        {
          try
          {
            CommandObj.Bindings = AShortCut;
          }
          catch (Exception ex)
          {
            System.Diagnostics.Debug.WriteLine("Cannot add shortcut: " + ex.ToString());
          }
        }

        // Using our command, add a menuitem to end of our main menu 
        ButtonObj = (CommandBarButton)CommandObj.AddControl(commandBar, commandBar.Controls.Count + 1);

        // Set seperator on menu item
        ButtonObj.BeginGroup = ASeparator;

        return CommandObj;
      }
      catch (Exception ex)
      {
        System.Diagnostics.Trace.WriteLine(ex.ToString());
        throw;
      }
    }
		*/
		public void RemoveCommands(string startText)
		{
			foreach (Command c in _applicationObject.Commands)
			{
				if (c.Name != null)
				{
					if (c.Name.StartsWith(startText))
					{
						WSLog.LogInfo("Removed: {0}", c.Name);
						c.Delete();
					}
					else if (c.Name.IndexOf("Widgetsphere") != -1)
					{
						WSLog.LogInfo("Left: {0}", c.Name);
					}
				}
			}
		}

		#region Debug Methods
#if DEBUG
		/*
    public void DebugWriteCommandBarNameByControlCaption(_DTE objDTE, string sControlCaption)
    {
      try
      {
        foreach(CommandBar objCommandBar in (CommandBars)objDTE.CommandBars)
        {
          foreach(CommandBarControl objCommandBarControl1 in objCommandBar.Controls)
          {
            if (objCommandBarControl1.Caption.IndexOf(sControlCaption) >= 0)
            {
              System.Diagnostics.Debug.WriteLine("----------------------------------------");
              System.Diagnostics.Debug.WriteLine("Candidate CommandBar Name: " + "\"" + objCommandBar.Name + "\"");
              System.Diagnostics.Debug.WriteLine("Captions on this command bar:");

              foreach(CommandBarControl objCommandBarControl2 in objCommandBar.Controls)
              {
                System.Diagnostics.Debug.WriteLine("  " + objCommandBarControl2.Caption);
              }
            }
          }
        }
      }
      catch (Exception ex)
      {
        System.Diagnostics.Trace.WriteLine(ex.ToString());
        throw;
      }
    }
		 */
#endif
		#endregion

	}
}